<template>
  <div class="subgraph-container">
    <!-- 图标按钮 -->
    <img 
    class="icon add-node" 
    src="@/assets/icons/add.svg" 
    @click="addNodeMode()"
    title="Add Node"
    alt="Add Node"
  />
    <img 
    class="icon add-edge" 
    src="@/assets/icons/link.svg" 
    @click="addEdgeMode()"
    title="Add Edge"
    alt="Add Edge"
  />
  <img 
    class="icon remove-edge" 
    src="@/assets/icons/cut.svg" 
    @click="removeEdgeMode()"
    title="Remove Edge"
    alt="Remove Edge"
  />
  <img 
    class="icon revoke" 
    src="@/assets/icons/revoke.svg" 
    @click="revokeMode()"
    title="Revoke"
    alt="Revoke"
  />
  <img 
    class="icon save" 
    src="@/assets/icons/save.svg" 
    @click="saveMode()"
    title="Save"
    alt="Save"
  />
    <!-- ECharts 容器 -->
    <div ref="chartContainer" style="width: 100%;height:50vh;"></div>
    <!-- 添加节点表单 -->
    <div v-if="showAddNodeForm" class="add-node-form">
      <h4>Add New Node</h4>
      <label for="node-id">ID (Same as Name):</label>
      <input id="node-id" v-model="newNodeId" placeholder="Enter ID..." />

      <label for="node-category">Category:</label>
      <select id="node-category" v-model="newNodeCategory">
        <option v-for="category in categories" :key="category" :value="category">{{ category }}</option>
      </select>

      <button @click="submitNewNode">Submit</button>
      <button @click="cancelAddNode">Cancel</button>
    </div>
  </div>
</template>

<script>
// 引入 ECharts 主模块
import * as echarts from "echarts/core";
// 引入图表类型，例如柱状图
import { GraphChart } from "echarts/charts";
// 引入组件，例如提示框、标题、图例
import { TitleComponent, TooltipComponent, LegendComponent } from "echarts/components";
// 引入 Canvas 渲染器
import { CanvasRenderer } from "echarts/renderers";
import { mapState } from "vuex";
import axios from "axios";

// 注册必要的组件
echarts.use([
  GraphChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  CanvasRenderer,
]);

export default {
  name: "EChartsComponent",
  data() {
    return {
      // 存储 ECharts 实例
      myChart: null,
      mode: null, // 当前模式：'add-edge' 或 'remove-edge'
      selectedNodes: [], // 存储选中的节点，用于添加边或删除边
      operationHistory: [], // 操作历史栈
      showAddNodeForm: false, // 控制输入框的显示/隐藏
      newNodeId: '', // 用户输入的新节点ID
      newNodeCategory: 'Root', // 用户选择的新节点类别，默认为Root
      categories: ['Root', 'FirstDegree', 'SecondDegree'], // 可供选择的类别列表
      dataResult: null // 创建一个空的 dataResult 来接收全局中的 dataResult
    };
  },
  computed: {
    // 不再直接映射 dataResult，以避免命名冲突
    ...mapState({
      globalDataResult: state => state.dataResult // 使用不同的名称来访问 store 中的数据
    })
  },
  watch: {
    globalDataResult(newData) {
      console.log('globalDataResult changed:', newData); // 调试：查看接收到的新数据
      if (newData && this.myChart) {
        // 更新组件内部的 dataResult
        this.dataResult = newData;
        console.log('Updating chart with new dataResult:', this.dataResult); // 调试：检查更新的dataResult
        this.updateChart(this.dataResult); // 如果 dataResult 更新，则更新图表
      } else {
        console.log('Either newData or myChart is not available for updating the chart.');
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  },
  methods: {
    normalizeLink(link) {
      const [source, target] = link;
      return source < target ? [source, target] : [target, source];
    },
    initChart() {
      const chartDom = this.$refs.chartContainer;

      // 确认 chartDom 存在并且不是一个空的元素
      if (!chartDom) {
        console.error("Chart container is not available.");
        return;
      }

      // 初始化图表实例
      this.myChart = echarts.init(chartDom);

      if (!this.myChart) {
        console.error("Failed to initialize ECharts instance.");
        return;
      }

      // 如果 dataResult 已经存在，则立即用它来设置图表选项
      if (this.globalDataResult) {
        this.dataResult = this.globalDataResult;
        this.updateChart(this.dataResult);
      }
    },
    updateChart(data) {
      // 设置图表配置项和数据
      const option = {
        legend: {
          data: data.categories.map(cat => cat.name), // 确保图例显示类别名称
          top: 'top' // 可选：调整图例位置
        },
        series: [
          {
            type: "graph",
            layout: "force",
            categories: data.categories,
            data: data.nodes.map((node) => ({
              ...node,
              value: node.vector.reduce((sum, cur) => sum + cur, 0), // 计算节点的总权重
            })),
            links: data.links.map((link) => ({
              source: link[0],
              target: link[1],
            })),
            roam: true, // 开启缩放与拖拽
            draggable: true, // 开启节点拖拽
            label: {
              show: true,
              position: "right",
            },
            force: {
              edgeLength: 150,
              repulsion: 300,
              gravity: 0.08,
            },
            lineStyle: {
              curveness: 0,
            },
            color: ["#c23531", "#03B318FF", "#0059FFFF"],
          },
        ],
      };

      // 使用刚指定的配置项和数据显示图表。
      this.myChart.setOption(option);

      // 监听节点点击事件
      this.myChart.on('click', (params) => {
        console.log('Clicked:', params); // 打印点击事件参数
        if (this.mode === 'add-edge') {
          this.addEdge(params);
        } else if (this.mode === 'remove-edge') {
          this.removeEdge(params);
        }
      });
    },

    addNodeMode() {
      this.showAddNodeForm = true;
      console.log("Add node mode activated");
    },
    addEdgeMode() {
      this.mode = 'add-edge';
      this.selectedNodes = [];
      console.log("Add edge mode activated");
    },
    removeEdgeMode() {
      this.mode = 'remove-edge';
      console.log("Remove edge mode activated");
    },
    revokeMode() {
    if (this.operationHistory.length === 0) {
      console.log("No operations to revoke.");
      return;
    }

    const lastOperation = this.operationHistory.pop();
    const { action, link } = lastOperation;

    // 深拷贝当前的 links 数组，确保不会影响原始数据
    let currentLinks = JSON.parse(JSON.stringify(this.dataResult.links));

    if (action === 'add') {
      // 如果是添加操作，则移除这条边
      console.log('Revoking add operation for link:', link);
      const normalizedLink = this.normalizeLink([link.source, link.target]);
      currentLinks = currentLinks.filter(([source, target]) =>
        !(source === normalizedLink[0] && target === normalizedLink[1])
      );

      // 更新 ECharts 图表中的 links
      this.myChart.setOption({
        series: [{
          type: 'graph',
          links: currentLinks.map(([source, target]) => ({ source, target })),
        }]
      });
      
      // 同步更新 dataResult 中的 links
      this.dataResult.links = currentLinks;
    } else if (action === 'remove') {
      // 如果是移除操作，则重新添加这条边
      console.log('Revoking remove operation for link:', link);
      const normalizedLink = this.normalizeLink([link.source, link.target]);
      currentLinks.push(normalizedLink);

      // 更新 ECharts 图表中的 links
      this.myChart.setOption({
        series: [{
          type: 'graph',
          links: currentLinks.map(([source, target]) => ({ source, target })),
        }]
      });

      // 同步更新 dataResult 中的 links
      this.dataResult.links = currentLinks;
    }

    console.log('Operation revoked successfully.');
  },

  async saveMode() {
    try {
      console.log("Saving the current subgraph...");

      // 获取最新的 dataResult（假设它已经包含所有更改）
      const payload = this.dataResult;

      // 定义请求URL和配置
      const url = 'http://localhost:5000/save-graph';
      const config = {
        headers: {
          'Content-Type': 'application/json'
        }
      };

      // 发送POST请求到后端
      const response = await axios.post(url, payload, config);

      // 处理响应
      if (response.status === 200) {
        console.log("Graph saved successfully:", response.data);
        // 根据需要更新UI或状态
        this.successMessage = 'Graph saved successfully.';
      } else {
        console.error("Failed to save graph:", response.statusText);
        this.errorMessage = 'Failed to save graph. Please try again.';
      }
    } catch (error) {
      console.error('There was an error saving the graph!', error);
      if (error.response) {
        // 请求已发出，但服务器响应了一个状态码不在2xx范围内
        console.error("Server responded with status:", error.response.status);
        this.errorMessage = `Failed to save graph. Server responded with status: ${error.response.status}`;
      } else if (error.request) {
        // 请求已发出，但没有收到响应
        console.error("No response received from server.");
        this.errorMessage = 'Failed to save graph. No response received from server.';
      } else {
        // 捕获了其他类型的错误
        this.errorMessage = 'Failed to save graph. Please check your input and try again.';
      }
    }
  },

  submitNewNode() {
    if (!this.newNodeId) {
      alert('Please enter an ID.');
      return;
    }

    const newNode = {
      id: this.newNodeId,
      name: this.newNodeId,
      category: this.newNodeCategory,
      vector: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // 默认向量值
    };

    let currentNodes = this.myChart.getOption().series[0].data.slice(); // 创建副本
    currentNodes.push(newNode);

    // 更新 dataResult 中的 nodes
    this.dataResult.nodes = [...this.dataResult.nodes, newNode];

    this.myChart.setOption({
      series: [{
        type: 'graph',
        data: currentNodes,
      }]
    });

    // 记录操作到历史栈，并清空撤销历史栈
    this.operationHistory.push({ action: 'addNode', node: newNode });
    this.revokeHistory = [];

    console.log('Node added successfully.');

    // 关闭表单
    this.cancelAddNode();
  },

  cancelAddNode() {
    this.showAddNodeForm = false;
    this.newNodeId = '';
    this.newNodeCategory = 'Root';
  },

  addEdge(params) {
    if (this.mode !== 'add-edge') return;

    console.log('Attempting to add an edge with params:', params);

    if (params.dataType === 'node') {
      this.selectedNodes.push(params.data.id);
      if (this.selectedNodes.length === 2) {
        const newLinkNormalized = this.normalizeLink(this.selectedNodes);
        console.log('Adding new normalized link:', newLinkNormalized);

        // 检查是否已经存在该边，避免重复添加
        if (!this.dataResult.links.some(([source, target]) =>
          source === newLinkNormalized[0] && target === newLinkNormalized[1])) {

          let currentLinks = this.myChart.getOption().series[0].links.slice(); // 创建副本
          currentLinks.push({ source: newLinkNormalized[0], target: newLinkNormalized[1] });

          // 更新 dataResult 中的 links
          this.dataResult.links.push([newLinkNormalized[0], newLinkNormalized[1]]);

          this.myChart.setOption({
            series: [{
              type: 'graph',
              links: currentLinks,
            }]
          });

          // 记录操作到历史栈
          this.operationHistory.push({ action: 'add', link: { source: newLinkNormalized[0], target: newLinkNormalized[1] } });

          this.selectedNodes = []; // 清空选择
          console.log('Edge added successfully.');
        } else {
          console.log('Edge already exists.');
          this.selectedNodes = [];
        }
      }
    }
  },

  removeEdge(params) {
    if (this.mode !== 'remove-edge') return;

    console.log('Attempting to remove an edge with params:', params);

    if (params.dataType === 'edge') {
      const removedLinkNormalized = this.normalizeLink([params.data.source, params.data.target]);

      // 更新 ECharts 图表中的 links
      let currentLinks = this.myChart.getOption().series[0].links.slice(); // 创建副本
      const updatedLinks = currentLinks.filter(link => 
        !(link.source === removedLinkNormalized[0] && link.target === removedLinkNormalized[1])
      );

      // 同步更新 dataResult 中的 links
      this.dataResult.links = this.dataResult.links.filter(([source, target]) =>
        !(source === removedLinkNormalized[0] && target === removedLinkNormalized[1])
      );

      this.myChart.setOption({
        series: [{
          type: 'graph',
          links: updatedLinks,
        }]
      });

      // 记录操作到历史栈
      this.operationHistory.push({ action: 'remove', link: { source: removedLinkNormalized[0], target: removedLinkNormalized[1] } });

      console.log('Edge removed successfully.');
    }
  },
  },
};
</script>




<style scoped>
.add-node-form {
  position: absolute;
  bottom: 10px;
  left: 10px;
  background-color: white;
  padding: 10px;
  border: 1px solid #ccc;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.add-node-form h4 {
  margin-top: 0;
}

.add-node-form label {
  display: block;
  margin-bottom: 5px;
}

.add-node-form input, .add-node-form select {
  width: 100%;
  margin-bottom: 10px;
}

.add-node-form button {
  margin-right: 5px;
}

/* 确保其他样式不变 */
.subgraph-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.toolbar {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  align-items: center;
}

.icon {
  width: 20px;
  height: 20px;
  margin-left: 10px;
  margin-top: 15px;
  cursor: pointer;
}
</style>